import * as THREE from "../../../../modules/three/three.module.js";
import ConvexAreaVO from "../../model/ConvexAreaVO.js";
import World3dEvent from "../../scene/event/World3dEvent.js";

const mtl = new THREE.MeshBasicMaterial({
  transparent: true,
  opacity: 0.9,
  color: '#e86833',
  polygonOffset: true,
  polygonOffsetFactor: -1,
  polygonOffsetUnits: -1,
});

const defaultColor = '#c40022'
const selectColor = '#0b7'

function findScene(obj3d) {
  let parent = obj3d.parent
  while (parent) {
    if (parent instanceof THREE.Scene) {
      return parent
    }
    parent = parent.parent
  }
  return null
}

export default class ConvexAreaMesh extends THREE.Mesh {
  static defaultColor = defaultColor;
  /**
   * @type {ConvexAreaVO}
   */
  vo
  _select = false

  constructor(geometry = new THREE.BufferGeometry(), material = mtl.clone()) {
    super(geometry, material);
  }

  toggleSelectArea(selected) {
    if (this._select === selected) {
      return
    }
    this._select = selected
    this.material.opacity = selected ? 0.4 : 0.9;
    this.children.forEach(it => {
      if (it.material) {
        it.material.color.setStyle(selected ? selectColor : defaultColor)
      }
    });
    const scene = findScene(this);
    if (!scene) {
      return;
    }
    if (selected) {
      const event = World3dEvent.surfaceAreaSelected
      event.value.color = '#' + this.material.color.getHexString()
      event.value.areaName = this.vo.id
      scene.dispatchEvent(event)
    } else {
      scene.dispatchEvent(World3dEvent.clearPaneSelection)
    }
  }

  changeConvexColor(colorStr) {
    const color = this.material.color;
    color.setStyle(colorStr);
  }

  /**
   * @param {ShapeExtract} shapeExtract
   */
  createVO(shapeExtract) {
    const vo = new ConvexAreaVO();
    vo.cameraStates = shapeExtract.cameraStates.slice();
    vo.cutPoints = shapeExtract.cutPoints.slice();
    this.vo = vo;
  }

  initContour(cutLines) {
    cutLines.forEach(it => this.add(it))
  }

  initByVO(vo) {
    this.vo = vo;
    this.geometry = vo.areaGeometry;
    this.material.color.setStyle(vo.color);
    const lineMtl = new THREE.LineBasicMaterial({
      color: defaultColor,
      transparent: true,
      // depthTest: false,
      // depthWrite: false,
    });
    vo.cutLineGeometries.forEach(geometry => {
      const lineSegment = new THREE.LineSegments(geometry, lineMtl);
      this.add(lineSegment)
    });
    return this;
  }

  updateVO() {
    this.vo.color = '#' + this.material.color.getHexString();
    this.vo.areaGeometry = this.geometry;
    this.vo.cutLineGeometries.length = 0;
    this.children.forEach(it => {
      if (it instanceof THREE.LineSegments) {
        this.vo.cutLineGeometries.push(it.geometry);
      }
    });
  }
}
